package com.freecloud.javabasics.thread.simple;

import com.freecloud.common.LoggerUtil;

/**
 * Synchronized的修饰方法
 *
 * 两种代表表现形式
 * 两种作用范围（对象锁、类锁）区别是否跨对象跨线程被保护
 * @Author: maomao
 * @Date: 2020-02-10 08:07
 */
public class SynchronizedDemo {

    /**
     * 修饰实例方法
     * 对象锁
     */
    public synchronized void test1(String str){
        LoggerUtil.println("test1: %s" , str);
    }

    /**
     * 修饰代码块
     * 对象锁、可控制粒度
     */
    public void test3(){
        //前后无代码的情况与test1相同
        synchronized (this){
            LoggerUtil.println("test3");
        }
    }

    /**
     * 修饰静态方法
     * 全局琐
     */
    public static synchronized void test2(){
        LoggerUtil.println("test2");
    }

    /**
     * 修饰代码块
     * 可控制粒度
     */
    public void test4(String str){
        //前后无代码与test2相同
        synchronized (SynchronizedDemo.class){
            LoggerUtil.println("test4: %s" , str);
        }
    }

    /**
     * 使用空的锁对象，会报空指针错误
     */
    public void test5(){
        String lock = null;
        synchronized (lock){
            LoggerUtil.println("test5: ");
        }
    }

    /**
     * 内存布局
     *
     * 对象头  ---> age、锁标记、偏向锁标记
     *
     * 实例数据
     *
     * 填充
     */

    public static void main(String[] args) {
        SynchronizedDemo demo1 = new SynchronizedDemo();
        SynchronizedDemo demo2 = new SynchronizedDemo();

        new Thread(()-> demo1.test1("A")).start();
        new Thread(()-> demo2.test1("B")).start();

        new Thread(()-> demo1.test4("A")).start();
        new Thread(()-> demo2.test4("B")).start();

        new Thread(()-> demo2.test5()).start();
    }
}
